package util.io;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;

class ResourcesUtilBase {
    private static final Logger log = LoggerFactory.getLogger(ResourcesUtilBase.class);
    private static final ClassLoaderAccessor THREAD_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
        protected ClassLoader doGetClassLoader() throws Throwable {
            return Thread.currentThread().getContextClassLoader();
        }
    };
    private static final ClassLoaderAccessor CLASS_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
        protected ClassLoader doGetClassLoader() throws Throwable {
            return ResourcesUtilBase.class.getClassLoader();
        }
    };
    private static final ClassLoaderAccessor SYSTEM_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
        protected ClassLoader doGetClassLoader() throws Throwable {
            return ClassLoader.getSystemClassLoader();
        }
    };

    public ResourcesUtilBase() {
    }

    /**
     *从类路径下获取资源
     * @param name 类路径。如:config/jdbc.properties
     * @return
     */
    public static InputStream getResourceAsStream(String name) {
        InputStream is = THREAD_CL_ACCESSOR.getResourceStream(name);
        if(is == null) {
            if(log.isTraceEnabled()) {
                log.trace("Resource [" + name + "] was not found via the thread context ClassLoader.  Trying the " + "current ClassLoader...");
            }

            is = CLASS_CL_ACCESSOR.getResourceStream(name);
        }

        if(is == null) {
            if(log.isTraceEnabled()) {
                log.trace("Resource [" + name + "] was not found via the current class loader.  Trying the " + "system/application ClassLoader...");
            }

            is = SYSTEM_CL_ACCESSOR.getResourceStream(name);
        }

        if(is == null && log.isTraceEnabled()) {
            log.trace("Resource [" + name + "] was not found via the thread context, current, or " + "system/application ClassLoaders.  All heuristics have been exhausted.  Returning null.");
        }

        return is;
    }




    private abstract static class ExceptionIgnoringAccessor implements ClassLoaderAccessor {
        private ExceptionIgnoringAccessor() {
        }
        public InputStream getResourceStream(String name) {
            InputStream is = null;
            ClassLoader cl = this.getClassLoader();
            if(cl != null) {
                is = cl.getResourceAsStream(name);
            }
            return is;
        }

        protected final ClassLoader getClassLoader() {
            try {
                return this.doGetClassLoader();
            } catch (Throwable var2) {
                if(ResourcesUtilBase.log.isDebugEnabled()) {
                    ResourcesUtilBase.log.debug("Unable to acquire ClassLoader.", var2);
                }

                return null;
            }
        }

        protected abstract ClassLoader doGetClassLoader() throws Throwable;
    }


    private interface ClassLoaderAccessor {
        InputStream getResourceStream(String var1);
    }
}